//
//  UserManager.swift
//  SitPosition
//
//  Created by apple on 2018/12/22.
//  Copyright © 2018 apple. All rights reserved.
//

import Foundation
import Alamofire


/**
 * 登录成功、失败通知
 */
let UserLoginSuccess = NSNotification.Name("user.login.success")
let UserLoginUnsuccess = NSNotification.Name("user.login.unsuccess")
let UserAskRole = NSNotification.Name("user.ask.role")
let UserLogedout = NSNotification.Name("user.logedout")


/**
 * 用户管理器（核心类）
 */
class UserManager {
    
    // 单例
    static let manager: UserManager = UserManager()
    
    // 当前用户角色
    public var role: UserRole {
        get { return Preferences.userRole }
        set { Preferences.userRole = newValue }
    }
    // 用户自己的IM账号
    public var userIMAcount : User.IMAccount? {
        guard let user = user else { return nil }
        var imAccount: User.IMAccount? = nil
        switch UserManager.manager.role {
        case .student:
            return user.studentIMAccount
        case .parent:
            return user.parentIMAccount
        }
    }
    // 用户对端（Peer）的IM账号
    public var peerIMAcount : User.IMAccount? {
        guard let user = user else { return nil }
        var imAccount: User.IMAccount? = nil
        switch UserManager.manager.role {
        case .student:
            return user.parentIMAccount
        case .parent:
            return user.studentIMAccount
        }
    }
    // 用户模型
    public private(set) var user: User? = nil
    // 更新用户令牌
    public func updateAccessToken(_ accessToken: AccessToken) -> Void {
        user?.accessToken = accessToken
        _save()
    }
    
    // app启动时调用一次
    public func onAppLaunch() {
        _restore()
        NetworkClient.instance.accessToken = user?.accessToken.access_token
    }
    
    // 判断用户是否已经登录？
    public func isLogin() -> Bool {
        guard let user_ = user, let userId = user_.id else { return false }
        return !userId.isEmpty && user_.isTokenValid
    }
    
    // 登录
    public func login(_ mobile: String, password: String, completion: ErrorCallback?) {
        // 实现用户登录逻辑
        // 登录成功：发送UserLoginSuccess
        // 登录失败：发送UserLoginUnsuccess
        NetworkClient.instance.login(mobile: mobile, password: password, success: { [weak self] (data) in
            guard let data_ = data else {
                NotificationCenter.default.post(name: UserLoginUnsuccess, object: nil)
                completion?(SPError.unexpectedServerResponse)
                return
            }
            do {
                let decoder = JSONDecoder()
                let user = try decoder.decode(User.self, from: data_)
                self?.user = user
                self?._save()
                NetworkClient.instance.accessToken = user.accessToken.access_token
                NotificationCenter.default.post(name: UserLoginSuccess, object: nil)
                NotificationCenter.default.post(name: UserAskRole, object: nil)
                completion?(nil)
            } catch {
                print(error.localizedDescription)
                NotificationCenter.default.post(name: UserLoginUnsuccess, object: nil)
                completion?(error)
            }
        }) { (error) in
            print(error?.networkErrorMessage ?? "登录发生未知错误")
            NotificationCenter.default.post(name: UserLoginUnsuccess, object: nil)
            completion?(error)
        }
    }
    
    // 注册
    public func register(mobile: String,
                         code: String,
                         password: String,
                         username: String,
                         invitCode: String?,
                         completion: ErrorCallback?) {
        NetworkClient.instance.registerUser(
            mobile: mobile,
            code: code,
            password: password,
            username: username,
            invitCode: invitCode,
            success: { [weak self] data in
                // 检查参数
                guard let data_ = data else {
                    completion?(SPError.unexpectedServerResponse)
                    return
                }
                // 注册成功
                do {
                    let decoder: JSONDecoder = JSONDecoder()
                    let user = try decoder.decode(User.self, from: data_)
                    self?.user = user
                    self?._save()
                    NetworkClient.instance.accessToken = user.accessToken.access_token
                    NotificationCenter.default.post(name: UserLoginSuccess, object: nil)
                    NotificationCenter.default.post(name: UserAskRole, object: nil)
                    completion?(nil)
                } catch {
                    completion?(error)
                }
        }, failure: { error in
            // 注册失败
            completion?(error)
            
            if let error_ = error {
                print(error_.localizedDescription)
            }
        })
    }
    
    // 找回密码
    func resetPassword(mobile: String,
                       code: String,
                       password: String,
                       completion: ErrorCallback?) {
        NetworkClient.instance.resetPassword(mobile: mobile, code: code, password: password, success: { [weak self] (data) in
            guard let sself = self else { return }
            guard let data_ = data else {
                completion?(SPError.unexpectedServerResponse)
                return
            }
            do {
                let decoder: JSONDecoder = JSONDecoder()
                let user: User = try decoder.decode(User.self, from: data_)
                sself.user = user
                sself._save()
                NetworkClient.instance.accessToken = user.accessToken.access_token
                completion?(nil)
            } catch {
                print(error.localizedDescription)
                completion?(error)
            }
        }, failure: { error in
            // 注册失败
            completion?(error)
            
            if let error_ = error {
                print(error_.localizedDescription)
            }
        })
    }
    
    // 登出
    func logout() {
        user = nil
        _save()
        NetworkClient.instance.accessToken = nil
        NotificationCenter.default.post(name: UserLogedout, object: nil)
    }
}

// MARK: - 保存、恢复用户模型

extension UserManager {
    
    // 钥匙链键名
    var userFile: String {
        return "user.model"
    }
    
    // 从钥匙链读取用户登录状态
    func _restore() {
        guard let path = try? Paths.persistentPath(userFile) else {
            user = nil
            return
        }
        guard let userData = try? Data(contentsOf: URL(fileURLWithPath: path)) else {
            user = nil
            return
        }
        let decoder = JSONDecoder()
        if let user_ = try? decoder.decode(User.self, from: userData),
            user_.isTokenValid {
            user = user_
            NotificationCenter.default.post(name: UserLoginSuccess, object: nil)
        } else {
            user = nil
            try? FileManager.default.removeItem(atPath: path)
        }
    }
    
    // 保存用户登录状态到钥匙链
    func _save() {
        guard let path = try? Paths.persistentPath(userFile) else {
            return
        }
        if let user_ = user {
            let encoder = JSONEncoder()
            if let userData: Data = try? encoder.encode(user_) {
                try? userData.write(to: URL(fileURLWithPath: path))
            } else {
                try? FileManager.default.removeItem(atPath: path)
            }
        } else {
            try? FileManager.default.removeItem(atPath: path)
        }
    }
}
